package com.yzq.os.spider.v.service.domain;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import com.yzq.os.spider.v.dao.SearchEngineDao;
import com.yzq.os.spider.v.domain.SearchEngine;
import com.yzq.os.spider.v.service.inter.OuterSystemService;
import com.yzq.os.spider.v.service.queryurl.CreateQueryURL;

@Service
public class SearchEngineService {

	private static Logger logger = Logger.getLogger(SearchEngineService.class);

	private static final Map<Integer, String> METHOD_MAP = new HashMap<Integer, String>();
	static{
		METHOD_MAP.put(SearchEngine.METHOD_GET, "GET");
		METHOD_MAP.put(SearchEngine.METHOD_POST, "POST");
	}
	
	private static final Map<Integer, String> ENCODE_MAP = new HashMap<Integer, String>();
	static {
		ENCODE_MAP.put(0, "GB18030");
		ENCODE_MAP.put(1, "GB2312");
		ENCODE_MAP.put(2, "GBK");
		ENCODE_MAP.put(3, "UTF-8");
		ENCODE_MAP.put(4, "ISO-8859-1");
	}

	@Autowired
	private SearchEngineDao searchEngineDao;

	@Autowired
	private QueryURLService queryURLService;

	@Autowired
	private SearchEngineParamService searchEngineParamService;

	@Autowired
	private OuterSystemService etlSystemService;

	@Value("${app.path.spider.implements.class}")
	private String spiderImplClassPath;

	public static List<BasicNameValuePair> getMethods() {
		return getPairs(METHOD_MAP);
	}

	public static List<BasicNameValuePair> getEncodes() {
		return getPairs(ENCODE_MAP);
	}

	public static String getEncode(int encodeValue) {
		String encode = ENCODE_MAP.get(encodeValue);
		if (StringUtils.isNotBlank(encode)) {
			return encode;
		} else {
			return null;
		}
	}

	private static List<BasicNameValuePair> getPairs(Map<Integer, String> map) {
		List<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>();
		for (Entry<Integer, String> entry : map.entrySet()) {
			pairs.add(new BasicNameValuePair(entry.getValue(), String
					.valueOf(entry.getKey())));
		}
		return pairs;
	}

	public CreateQueryURL instantiateQueryURLClass(String createQueryURLClass) {
		CreateQueryURL createQueryURL = null;
		try {
			createQueryURL = (CreateQueryURL) BeanUtils.instantiate(getClass()
					.getClassLoader().loadClass(createQueryURLClass));
			createQueryURL.setSearchEngineService(this);
			createQueryURL
					.setSearchEngineParamService(searchEngineParamService);
		} catch (BeanInstantiationException e) {
			logger.error("", e);
		} catch (ClassNotFoundException e) {
			logger.error("", e);
		}
		return createQueryURL;
	}

	public void save(SearchEngine searchEngine) {
		int searchEngineId = searchEngineDao.save(searchEngine);
		queryURLService.createTable(searchEngineId);
	}

	public List<SearchEngine> findAllList() {
		List<SearchEngine> engines = searchEngineDao.findAllList();
		etlSystemService.setEngineWebsiteNames(engines);
		return engines;
	}

	public List<SearchEngine> findUIViews() {
		List<SearchEngine> engines = searchEngineDao.findAllList();
		if (CollectionUtils.isNotEmpty(engines)) {
			for (SearchEngine engine : engines) {
				Integer id = engine.getId();
				String name = engine.getName();
				engine.setName("(" + id + ")  " + name);
			}
		}
		return engines;
	}

	public SearchEngine findById(int searchEngineId) {
		return searchEngineDao.findById(searchEngineId);
	}

	public int countById(int searchEngineId) {
		return searchEngineDao.countById(searchEngineId);
	}

	public void update(SearchEngine searchEngine) {
		searchEngineDao.update(searchEngine);
	}

	public List<String> getSpiderImplClasses() {
		return getClassPaths(spiderImplClassPath);
	}

	public List<String> getClassPaths(String baseClasspath) {
		List<String> returnValues = new ArrayList<String>();
		try {
			File dir = ResourceUtils.getFile("classpath:" + baseClasspath);
			if (dir != null && dir.isDirectory() && dir.exists()) {
				Collection<File> files = FileUtils.listFiles(dir,
						new String[] { "class" }, false);
				if (CollectionUtils.isNotEmpty(files)) {
					String basePackageName = StringUtils.replaceEach(baseClasspath, new String[] { "/", "\\" },new String[] { ".", "." });
					for (File file : files) {
						String clazz = basePackageName + "."
								+ FilenameUtils.getBaseName(file.getName());
						returnValues.add(clazz);
					}
				} else {
					logger.info("Not have files under path:["
							+ dir.getAbsolutePath() + "]");
				}
			} else {
				logger.error("Dir file object is null........");
			}
		} catch (FileNotFoundException e) {
			logger.error("", e);
		}
		Collections.sort(returnValues);
		return returnValues;
	}

}
